﻿//=======================================================================================
//
//  Purpose: Main program for a simple web server for the Netduino Plus.
//
//  Copyright (C) 2011 Mark Stevens
//
//  This software is destributed under the MS-PL licence agreement a copy of which can
//  be found on the codeplex page http://netduinoledcontrol.codeplex.com and in the
//  Licence.txt file distributed with this project.
//
//=======================================================================================
using System;
using System.Threading;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware;
using System.IO;

namespace NetduinoWebServer
{
    public class Program
    {
        #region Constants

        /// <summary>
        /// Root directory for the web files.
        /// </summary>
        private const string WEB_ROOT = @"\SD\";

        #endregion

        #region Private variables.

        /// <summary>
        /// Web server instance.
        /// </summary>
        private static WebServer _webServer;

        /// <summary>
        /// On board LED - used to let the user know the program is still alive.
        /// </summary>
        private static OutputPort _onBoardLED;

        /// <summary>
        /// On board button - used by user to request confirmation the board is still alive.
        /// </summary>
        private static InterruptPort _onBoardButton;

        /// <summary>
        /// Number of milliseconds between samplks.
        /// </summary>
        private static int _sampleRate;

        /// <summary>
        /// Name of the file in which to store the data.
        /// </summary>
        private static string _fileName;

        /// <summary>
        /// Are we logging at hte moment?
        /// </summary>
        private static bool _logging;

        /// <summary>
        /// Timer used to trigger the collection of data.
        /// </summary>
        private static Timer _timer;

        /// <summary>
        /// Start time for the logging session (in Ticks).
        /// </summary>
        private static long _startTime;

        /// <summary>
        /// Analog pin to read data from.
        /// </summary>
        private static AnalogInput _analogInput;

        #endregion

        #region Constructor(s)

        /// <summary>
        /// Main program loop.
        /// </summary>
        public static void Main()
        {
            _logging = false;
            _onBoardLED = new OutputPort(Pins.ONBOARD_LED, false);
            _onBoardButton = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            _onBoardButton.OnInterrupt += new NativeEventHandler(onBoardButton_OnInterrupt);

            _webServer = new WebServer(WEB_ROOT, WebServer.HTTP_PORT);
            _webServer.ConfigurationChanged += new WebServer.ConfigurationChangedEvent(_webServer_ConfigurationChanged);
            _analogInput = new AnalogInput(Pins.GPIO_PIN_A0);
            _sampleRate = 50;
            _fileName = "Log.txt";
            _logging = false;

            Thread.Sleep(Timeout.Infinite);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Read the data from the analog pin and write to the log file.
        /// </summary>
        /// <param name="o"></param>
        private static void CollectData(object o)
        {
            string data;

            data = Utility.GetMachineTime().Ticks - _startTime + "," + _analogInput.Read();
            using (TextWriter tw = new StreamWriter(@"\SD\" + _fileName, true))
            {
                tw.WriteLine(data);
                tw.Close();
            }
        }

        #endregion

        #region Events

        /// <summary>
        /// Start or stop logging.
        /// </summary>
        private static void onBoardButton_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            if (data2 == 0)
            {
                if (_logging)
                {
                    _timer = null;
                    _onBoardLED.Write(false);
                    _logging = false;
                }
                else
                {
                    using (TextWriter tw = new StreamWriter(@"\SD\" + _fileName, false))
                    {
                        tw.WriteLine("Ticks,Data");
                        tw.Close();
                    }
                    _startTime = Utility.GetMachineTime().Ticks;
                    _timer = new Timer(new TimerCallback(CollectData), null, 0, _sampleRate);
                    _onBoardLED.Write(true);
                    _logging = true;
                }
            }
        }

        /// <summary>
        /// Configuration change has been requested.
        /// </summary>
        private static void _webServer_ConfigurationChanged(object sender, ConfigurationEventArgs e)
        {
            _sampleRate = e.SampleRate;
            _fileName = e.FileName;
        }

        #endregion
    }
}
